{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## PyTorch线性回归"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ">公式推导如下，最早看的Andrew Ng的视频，三年多了，今天手推了下，还没忘记，核心思想算是理解了。\n",
    "![线性回归GD推导](https://upload-images.jianshu.io/upload_images/8570704-86ba34bcadd2f23a.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import torch\n",
    "#import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [],
   "source": [
    "#获取数据\n",
    "x_train = np.array([[3.3], [4.4], [5.5], [6.71], [6.93], [4.168], \n",
    "[9.779], [6.182], [7.59], [2.167], [7.042], \n",
    "[10.791], [5.313], [7.997], [3.1]], dtype=np.float32) \n",
    "y_train = np.array([[1.7], [2.76], [2.09], [3.19], [1.694], [1.573], \n",
    "[3.366], [2.596], [2.53], [1.221], [2.827], \n",
    "[3.465], [1.65], [2.904], [1.3]], dtype=np.float32)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [],
   "source": [
    "#转换数据格式到tensor\n",
    "x_train = torch.from_numpy(x_train)\n",
    "y_train = torch.from_numpy(y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "W: tensor([1.2399], requires_grad=True)\n",
      "b: tensor([0.9948], requires_grad=True)\n"
     ]
    }
   ],
   "source": [
    "#构建参数\n",
    "W = torch.randn(1, requires_grad=True)\n",
    "b = torch.randn(1, requires_grad=True)\n",
    "print('W: %s' %W)\n",
    "print('b: %s' %b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [],
   "source": [
    "#构建模型\n",
    "def LR(x):\n",
    "    return W*x+b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [],
   "source": [
    "#定义损失函数\n",
    "def loss_func(y_, y):\n",
    "    return torch.mean((y_ - y)**2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [],
   "source": [
    "#反向传播，得到梯度\n",
    "#loss.backward()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [],
   "source": [
    "#learning rate\n",
    "lr = 1e-2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch: 0, loss:43.80794906616211\n",
      "epoch: 1, loss:0.9779185652732849\n",
      "epoch: 2, loss:0.18526847660541534\n",
      "epoch: 3, loss:0.17059212923049927\n",
      "epoch: 4, loss:0.1703134924173355\n",
      "epoch: 5, loss:0.17030125856399536\n",
      "epoch: 6, loss:0.17029404640197754\n",
      "epoch: 7, loss:0.17028699815273285\n",
      "epoch: 8, loss:0.17027997970581055\n",
      "epoch: 9, loss:0.17027296125888824\n",
      "epoch: 10, loss:0.17026600241661072\n",
      "epoch: 11, loss:0.1702590435743332\n",
      "epoch: 12, loss:0.17025215923786163\n",
      "epoch: 13, loss:0.17024533450603485\n",
      "epoch: 14, loss:0.17023850977420807\n",
      "epoch: 15, loss:0.1702316701412201\n",
      "epoch: 16, loss:0.17022494971752167\n",
      "epoch: 17, loss:0.17021827399730682\n",
      "epoch: 18, loss:0.1702115535736084\n",
      "epoch: 19, loss:0.17020490765571594\n"
     ]
    }
   ],
   "source": [
    "#梯度下降法更新参数\n",
    "for ite in range(20):\n",
    "    y_ = LR(x_train)\n",
    "    loss = loss_func(y_, y_train)\n",
    "    if ite > 0:\n",
    "        W.grad.zero_()\n",
    "        b.grad.zero_()\n",
    "    loss.backward() #反向传播\n",
    "    W.data = W.data - lr * W.grad.data #更新参数\n",
    "    b.data = b.data - lr * b.grad.data\n",
    "    print('epoch: {}, loss:{}'.format(ite, loss.item()))\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
